package com.admin.common.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池管理类
 * 
 * @author qyf 2016年11月2日
 *
 */
public class ThreadPoolManager {

    private static volatile ThreadPoolManager threadPoolManager;
    private static final int corePoolSize = 4; // 核心池的大小 运行线程的最大值 当线程池中的线程数目达到corePoolSize后，就会把多余的任务放到缓存队列当中；
    private static final int maximumPoolSize = 16; // 创建线程最大值
    private static final long keepAliveTime = 60 * 1000;// 线程没有执行任务时 被保留的最长时间 超过这个时间就会被销毁 直到线程数等于 corePoolSize
    private static final TimeUnit unit = TimeUnit.MILLISECONDS;// 闲置最长时间单位 毫秒

    private LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(6000);// 用来储存等待中的任务的容器。几种选择：ArrayBlockingQueue;LinkedBlockingQueue;SynchronousQueue;
    private ThreadPoolExecutor executor = null;

    private ThreadPoolManager() {
        executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }

    /**
     * 获取线程池管理对象
     * 
     * @return
     */
    public static ThreadPoolManager get() {
        if (threadPoolManager == null) {
            synchronized (ThreadPoolManager.class) {
                if (threadPoolManager == null) {
                    threadPoolManager = new ThreadPoolManager();
                }
            }
        }
        return threadPoolManager;
    }

    /**
     * 任务放入线程池
     * 
     * @param t
     */
    public void execute(Thread t) {
        executor.execute(t);
    }

    /**
     * 任务放入线程池
     * 
     * @param t
     */
    public void execute(Runnable t) {
        executor.execute(t);
    }

    /**
     * 返回 Future Future.getByFreightTemplatesIdAndProvinceId()可获得返回结果
     * 
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public <T> Future<T> submit(Callable<T> t) {
        return executor.submit(t);
    }

    /**
     * 销毁线程池
     */
    public void shutdown() {
        executor.shutdown();
    }
}
